package com.gugee.tiktok.data.consumer.blogger.core.main;

import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.gugee.common.thread.ScheduleTemplate;
import com.gugee.tiktok.common.model.mysql.Aweme;
import com.gugee.tiktok.common.model.spider.aweme.Aweme_list;
import com.gugee.tiktok.common.model.dal.blogger.AwemeRepository;
import com.gugee.tiktok.data.consumer.blogger.config.DataConsumerConfig;
import com.gugee.tiktok.data.consumer.blogger.core.service.BloggerClient;

import com.xiguaji.boot.filecenter.FileTemplate;
import com.xiguaji.boot.toolkit.DateTimeUtils;
import com.xiguaji.boot.toolkit.ThreadPoolUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: luolifeng
 * Date: 2020-10-14 20:57
 */

@Slf4j
@Component
public class SaveAwemeEventMain {
    @Autowired
    AwemeRepository awemeRepository;

    @Autowired
    Aweme.AwemeMapper awemeMapper;


    @Autowired
    BloggerClient bloggerClient;
    @Autowired
    FileTemplate fileTemplate;

    @Autowired
    ScheduleTemplate scheduleTemplate;


    @Value("${xiguaji.oss.bucket.tiktok.videoImg}")
    String picBucket;

    @NacosValue(value="${tiktok.data.threadpools.oss.downloadPicsParallelism}", autoRefreshed = true)
    int downloadPicsParallelism;
    @NacosValue(value="${tiktok.data.batchQuery.nums}", autoRefreshed = true)
    int batchNums;

    @Autowired
    DataConsumerConfig dataConsumerConfig;
    ForkJoinPool forkJoinPoolDownloadPics ;
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");

    @PostConstruct
    public void init() {
        log.info("SaveAwemeEventListener  init");
        forkJoinPoolDownloadPics = ThreadPoolUtils.forkJoinPool(downloadPicsParallelism, "downloadPics");
        scheduleTemplate.attach("downloadPics", forkJoinPoolDownloadPics);
    }

    public void handle(String bloggerType,long uid,List<Aweme_list> aweme_lists) {
        if (CollectionUtils.isEmpty(aweme_lists)) {
            return;
        }
        long start = System.currentTimeMillis();

        var awemeEntities = awemeMapper.mapper(aweme_lists);


        List<Aweme> existsAwemeList=batchQueryAwemes(awemeEntities);
        List<Aweme> update = new ArrayList<>(existsAwemeList.size());
        List<Aweme> insert = new ArrayList<>(awemeEntities.size()-existsAwemeList.size());
        Map<Long, Aweme> existsAwemeMap = existsAwemeList.stream().collect(Collectors.toMap(Aweme::getOAwemeId, a -> a,(k1, k2)->k1));

        awemeEntities.forEach(aweme -> {
//            if(aweme.getAnchor()!=null) {
//                System.out.println(aweme.getOAwemeId() + ":" + aweme.getAnchor());
//            }
//            log.info("uid={},size={},aweme={},OCover={}",uid,awemeEntities.size(),aweme.getId(),aweme.getOCover());
            LocalDateTime localDateTime = DateTimeUtils.localDateTimeBySecond(aweme.getOCreateTime());
            aweme.setDatecode(Integer.parseInt(localDateTime.format(formatter)));
            if(!StringUtils.isEmpty(bloggerType)){
                aweme.setBloggerType(bloggerType);
            }
            if(existsAwemeMap.containsKey(aweme.getOAwemeId())){
                Aweme a=existsAwemeMap.get(aweme.getOAwemeId());
                aweme.setId(a.getId());
                aweme.setScore(a.getScore());
                if(!dataConsumerConfig.isAwemePicUpdate()){
                    if(a.getOCover().contains("oss-us-east-1.aliyuncs.com")){
                        aweme.setOCover(a.getOCover());
                    }else if(a.getOCover().contains("s3.amazonaws.com")){
                        aweme.setOCover(a.getOCover().replace("s3.amazonaws.com","oss-us-east-1.aliyuncs.com"));
                    }
                }
            }

            if(aweme.getId() > 0){

                update.add(aweme);
             }else{
                insert.add(aweme);
            }
        });

        long batchUpdateTimes = System.currentTimeMillis();
        if(update.size() > 0){

            //重新更新视频图片，多线程下载图片
            if(dataConsumerConfig.isAwemePicUpdate()) {
                   try {
                        forkJoinPoolDownloadPics.submit(
                                () -> update.parallelStream().forEach(aweme -> aweme.setOCover(setS3Picture(aweme.getOAwemeId(), aweme.getOCover(), aweme.getOCreateTime())))
                        ).get();
                    } catch (InterruptedException | ExecutionException e) {
                        e.printStackTrace();
                    }

            }else{
//                log.info("************************************************************************");
            }
            awemeRepository.batchUpdate(update);
        }
        batchUpdateTimes=(System.currentTimeMillis()-batchUpdateTimes)/1000;
        long downPic=System.currentTimeMillis();
        //新视频，多线程下载图片
            try {
                forkJoinPoolDownloadPics.submit(
                        () -> insert.parallelStream().forEach(aweme -> aweme.setOCover(setS3Picture(aweme.getOAwemeId(), aweme.getOCover(),aweme.getOCreateTime())))
                ).get();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }


        downPic=(System.currentTimeMillis()-downPic)/1000;
        long batchInsertTimes=System.currentTimeMillis();
        if (insert.size() > 0){
            awemeRepository.batchSave(insert);
        }
        batchInsertTimes=(System.currentTimeMillis()-batchInsertTimes)/1000;

        long times=(System.currentTimeMillis()-start)/1000;
        if(times >dataConsumerConfig.getDebugTimeLimit()) {
            log.info("---------SaveAwemeEvent uid={},totals/times={}/{}s,updates/times={}/{}s , inserts/times={}/{}s,downpictures/times={}/{}s,awemes/s={} ",uid, awemeEntities.size(),times,update.size(),batchUpdateTimes,insert.size(),batchInsertTimes,insert.size(),downPic , awemeEntities.size()/times);
        }
    }
    public List<Aweme> batchQueryAwemes(List<Aweme> awemeList){

        int cnt=0;
        List<Long> tmpIds=new ArrayList<>(batchNums);
        List<Aweme> rst=new ArrayList<>(awemeList.size());

        for (Aweme e : awemeList) {
            tmpIds.add(e.getOAwemeId());
            cnt++;
            if(cnt%batchNums==0){
                rst.addAll(awemeRepository.findByoAwemeIdIn(tmpIds)) ;
                cnt=0;
                tmpIds.clear();
            }
        }
        //剩余
        if(cnt>0){
            rst.addAll(awemeRepository.findByoAwemeIdIn(tmpIds)) ;
            tmpIds.clear();
        }
        return rst;
    }


    private String setS3Picture(long awemeId,String coverUrl,long createTime){
        String s3Url= coverUrl;
        try {
//            log.info("awemeId={},s3Url={},createTime={}",awemeId,s3Url,createTime);
            s3Url = fileTemplate.putNetImg(picBucket,"video_" + DateTimeUtils.millsecond2DateStr(createTime,"yyyyMMdd") + "/" + awemeId,coverUrl);
//            log.info("awemeId={},s3Url={},createTime={}",awemeId,s3Url,createTime);

        } catch (Exception ioException) {
            //上传失败则当不曾上传过
            log.error("**************************************************"+ioException.getMessage());
        }
        if(StringUtils.isEmpty(s3Url)){
            s3Url= coverUrl;
            log.error("setOssPicture:awemeId={};coverUrl={};ossUrl={};createTime={}", awemeId, coverUrl,s3Url,createTime);
        }

        return s3Url;
    }


}
